package org.example.quartz.task;

import cn.hutool.db.Entity;
import cn.hutool.db.Session;
import cn.hutool.extra.spring.SpringUtil;
import cn.hutool.http.HttpRequest;
import com.alibaba.fastjson.JSONObject;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.example.quartz.service.LogService;
import org.example.quartz.service.OrgService;
import org.example.quartz.service.UtilService;
import org.example.quartz.util.DataSourceUtil;
import org.quartz.*;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Component;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;

@Slf4j
@Component
// 再Job被执行结束后，将会更新JobDataMap，这样下次Job执行后悔使用新的值而不是初始值
@PersistJobDataAfterExecution
// 同一时间将只有一个Job实例被执行，为了避免并发问题导致数据紊乱，建议这两个注解一起使用
@DisallowConcurrentExecution
public class CustomerQuartz implements QuartzTaskJob {

    Map<String, Object> gsMap = DataSourceUtil.getGS();
    //全局接口配置
    String IP = (String) gsMap.get("IP");
    String PORT = (String) gsMap.get("PORT");
    String ECC = (String) gsMap.get("ECC");
    String Bearer = (String) gsMap.get("Bearer");

    //日志
    LogService loginfo = SpringUtil.getBean(LogService.class);
    //orgService
    OrgService orgService = SpringUtil.getBean(OrgService.class);
    //orgService
    UtilService utilService = SpringUtil.getBean(UtilService.class);
    /**
     * 往来单位接口（供应商、客户）
     * 接口地址：GSCloud文档3.5
     * http://ip:port/api/jg/syncbddata/v1.0/bdsyncinterface/syncWldw
     **/
    @SneakyThrows
    @Override
    public void execute(JobExecutionContext context) {
        try {
            //传入变量 lastTime 最后抓取时间
            //链接BIP数据库，查询出需要同步的数据，根据TS时间进行判断。
            //TS从中间库表获取到最后一次更新时间，根据此时间进行增量查询推送；
            //中间库日志表记录推送日志，成功、失败、返回信息等（备查）
            //中间库记录最后推送数据的时间，根据时间进行下次查询的条件；
            //查询脚本
            /**
             *
             bd_custaddress  地址
             bd_custbank        银行
             * */
            String methodName = "CustomerQuartz";
            JdbcTemplate jdbcTemplate = SpringUtil.getBean(JdbcTemplate.class);
            //1、查询时间
            String ts = utilService.getTs(methodName, jdbcTemplate);
            String orgStr = utilService.getGSOrgStr(jdbcTemplate);
            //2、根据时间查询数据集 (停用和删除的过滤掉，暂不考虑，线下处理)
            String selectSQL = "SELECT--判断编码  客户01、供应商02、其他03\n" +
                    "(\n" +
                    "CASE WHEN CS.custenablestate = '2' AND CS.supenablestate != '2' THEN '01$'||CS.CODE \n" +
                    "WHEN CS.custenablestate != '2' AND CS.supenablestate = '2' THEN '02$'||CS.CODE \n" +
                    "WHEN CS.custenablestate = '2' AND CS.supenablestate = '2' THEN '03$'||CS.CODE \n" +
                    "END  ) AS CODE,\n" +
                    "CS.NAME AS NAME,\n" +
                    "--需按GSCloud系统往来单位类别定义中编号传递（后续提供）\n" +
                    "'publictest' AS TYPECODE,\n" +
                    "'集团内' AS TYPENAME,\n" +
                    "--需按GSCloud系统往来单位地区定义中编号传递  往来单位地区编号0001\n" +
                    "'' AS AREACODE,\n" +
                    "--地区名称\n" +
                    "'' AS AREANAME,\n" +
                    "--往来单位公私类型\n" +
                    "'1' AS DOMAINTYPE,\n" +
                    "--ORGCODE\n" +
                    "O.CODE AS ORGCODE,\n" +
                    "--默认交易币种编号\n" +
                    "'' AS DEFAULTCURRENCY,\n" +
                    "CS.PK_CUST_SUP AS ID," +
                    "CS.TS AS TS \n" +
                    "FROM\n" +
                    "BD_CUST_SUPPLIER CS\n" +
                    "LEFT JOIN ORG_ORGS O ON CS.PK_ORG = O.PK_ORG\n" +
                    "where\n" +
                    "CS.DR = 0\n" +
                    "AND \n" +
                    "CS.TS > '" + ts + "'" +
                    "AND \n" +
                    "O.CODE IN (" + orgStr + ")";
            //查询数据，根据数据结果推送给GS浪潮
            Session oracleSession = DataSourceUtil.getOracleSession();
            List<Entity> query = oracleSession.query(selectSQL);
            //拼装数据，推送给浪潮
            if (query.size() > 0) {
                for (Map<String, Object> gSmap : query) {
                    //更换gsCode
                    String gsCode = orgService.selectGsCode((String) gSmap.get("ORGCODE"), jdbcTemplate);
                    //客商PK主键(同客户主键、供应商主键)
                    String PK_CUST_SUP = (String) gSmap.get("ID");
                    //查询地址信息  bd_custaddress\bd_supaddress
                    //关联查询客户地址+供应商地址
                    String addressSQL = "--客户收货地址\n" +
                            "select\n" +
                            "'' AS CODE,\n" +
                            "'' AS COUNTRYORREGION,\n" +
                            "'' AS ADDRTYPE,\n" +
                            "'' AS ISMAIN,\n" +
                            "'' AS STREETNO,\n" +
                            "'' AS CONTACTNUM,\n" +
                            "'' AS REMARK\n" +
                            "from\n" +
                            "bd_custaddress\n" +
                            "where\n" +
                            "PK_CUSTOMER = '" + PK_CUST_SUP + "'\n" +
                            "UNION\n" +
                            "--供应商发货地址\n" +
                            "select\n" +
                            "'' AS CODE,\n" +
                            "'' AS COUNTRYORREGION,\n" +
                            "'' AS ADDRTYPE,\n" +
                            "'' AS ISMAIN,\n" +
                            "'' AS STREETNO,\n" +
                            "'' AS CONTACTNUM,\n" +
                            "'' AS REMARK \n" +
                            "from \n" +
                            "bd_supaddress\n" +
                            "where \n" +
                            "PK_SUPPLIER = '" + PK_CUST_SUP + "'";
                    List<Entity> addressMap = oracleSession.query(addressSQL);
                    //查询银行信息  bd_custbank
                    String bankaccountSQL = "--客户银行账号\n" +
                            "SELECT\n" +
                            "'' AS ACCOUNTCODE,\n" +
                            "'' AS ACCOUNTNAME,\n" +
                            "'' AS INBANK,\n" +
                            "'' AS ACCOUNTSTATE,\n" +
                            "'' AS PRIVATEORPUBLIC,\n" +
                            "'' AS CURRENCYLIST,\n" +
                            "'' AS ISMAIN,\n" +
                            "'' AS COUNTRY,\n" +
                            "'' AS PROVINCE,\n" +
                            "'' AS CITY,\n" +
                            "'' AS REMARK\n" +
                            "FROM\n" +
                            "BD_CUSTBANK\n" +
                            "WHERE \n" +
                            "PK_CUST = '" + PK_CUST_SUP + "'";
                    List<Entity> bankMap = oracleSession.query(bankaccountSQL);
                    //查询联系人信息
                    String contactSQL = "--客户联系人\n" +
                            "SELECT\n" +
                            "'' AS NAME,\n" +
                            "'' AS IDENTITYTYPE,\n" +
                            "'' AS IDENTITYNUMBER,\n" +
                            "'' AS GENDER,\n" +
                            "'' AS DUTY,\n" +
                            "'' AS TEL,\n" +
                            "'' AS ISMAIN,\n" +
                            "'' AS REMARK \n" +
                            "FROM\n" +
                            "BD_CUSTLINKMAN\n" +
                            "WHERE \n" +
                            "PK_CUSTOMER = '" + PK_CUST_SUP + "'\n" +
                            "UNION\n" +
                            "--供应商联系人\n" +
                            "SELECT\n" +
                            "'' AS NAME,\n" +
                            "'' AS IDENTITYTYPE,\n" +
                            "'' AS IDENTITYNUMBER,\n" +
                            "'' AS GENDER,\n" +
                            "'' AS DUTY,\n" +
                            "'' AS TEL,\n" +
                            "'' AS ISMAIN,\n" +
                            "'' AS REMARK  \n" +
                            "FROM\n" +
                            "BD_SUPLINKMAN\n" +
                            "WHERE \n" +
                            "PK_SUPPLIER = '" + PK_CUST_SUP + "'";
                    List<Entity> contactMap = oracleSession.query(contactSQL);
                    //根据公司、账套进行拆分推送，根据组织编码，查询出账套信息，如果有多个账套，轮询进行处理
                    List<Map<String, Object>> yyztCodeMap = orgService.selectZtCode((String) gSmap.get("ORGCODE"), jdbcTemplate);
                    //账簿轮询
                    for (int x = 0; x < yyztCodeMap.size(); x++) {
                        String yyztCode = (String) yyztCodeMap.get(x).get("yyztCode");
                        String orgCode = (String) yyztCodeMap.get(x).get("gsCode");
                        String GsJson =
                                "{\n" +
                                        "\"CODE\":\"" + gSmap.get("CODE").toString().replace("$", yyztCode) + "\",\n" +
                                        "\"NAME\":\"" + gSmap.get("Name") + yyztCode + "\",\n" +
                                        "\"TYPECODE\":\"" + gSmap.get("TYPECODE") + "\",\n" +
                                        "\"TYPENAME\":\"" + gSmap.get("TYPENAME") + "\",\n" +
                                        "\"AREACODE\":\"" + gSmap.get("AREACODE") + "\",\n" +
                                        "\"AREANAME\":\"" + gSmap.get("AREANAME") + "\",\n" +
                                        "\"DOMAINTYPE\":\"" + gSmap.get("DOMAINTYPE") + "\",\n" +
                                        "\"ORGCODE\":\"" + orgCode + "\",\n" +
                                        "\"DEFAULTCURRENCY\":\"" + gSmap.get("DEFAULTCURRENCY") + "\",\n" +
                                        "\"ADDRESS\":[\n";
                        //拼装地址信息
                        if (addressMap.size() > 0) {
                            for (Map<String, Object> addressObj : addressMap) {
                                GsJson +=
                                        "{\n" +
                                                "\"CODE\":\"" + addressObj.get("CODE") + "\",\n" +
                                                "\"COUNTRYORREGION\":\"" + addressObj.get("COUNTRYORREGION") + "\",\n" +
                                                "\"ADDRTYPE\":\"" + addressObj.get("ADDRTYPE") + "\",\n" +
                                                "\"ISMAIN\":\"" + addressObj.get("ISMAIN") + "\",\n" +
                                                "\"STREETNO\":\"" + addressObj.get("STREETNO") + "\",\n" +
                                                "\"CONTACTNUM\":\"" + addressObj.get("CONTACTNUM") + "\",\n" +
                                                "\"REMARK\":\"" + addressObj.get("REMARK") + "\"\n" +
                                                "     },";
                            }
                            //去掉拼接的最后一个字符
                            GsJson = GsJson.substring(0, GsJson.lastIndexOf(','));
                        }
                        GsJson += "],\n" +
                                " \"CONTACT\":[\n";
                        if (contactMap.size() > 0) {
                            for (Map<String, Object> contactObj : contactMap) {
                                GsJson += "{\n" +
                                        "\"NAME\":\"" + contactObj.get("NAME") + "\",\n" +
                                        "\"IDENTITYTYPE\":\"" + contactObj.get("IDENTITYTYPE") + "\",\n" +
                                        "\"IDENTITYNUMBER\":\"" + contactObj.get("IDENTITYNUMBER") + "\",\n" +
                                        "\"GENDER\":\"" + contactObj.get("GENDER") + "\",\n" +
                                        "\"DUTY\":\"" + contactObj.get("DUTY") + "\",\n" +
                                        "\"TEL\":\"" + contactObj.get("TEL") + "\",\n" +
                                        "\"ISMAIN\":\"" + contactObj.get("ISMAIN") + "\",\n" +
                                        "\"REMARK\":\"" + contactObj.get("REMARK") + "\"\n" +
                                        " },";
                            }
                            //去掉拼接的最后一个字符
                            GsJson = GsJson.substring(0, GsJson.lastIndexOf(','));
                        }
                        GsJson += "],\n" +
                                "\"BANKACCOUNTS\":[\n";
                        if (bankMap.size() > 0) {
                            for (Map<String, Object> bankObj : bankMap) {
                                GsJson += "{\n" +
                                        "\"ACCOUNTCODE\":\"" + bankObj.get("ACCOUNTCODE") + "\",\n" +
                                        "\"ACCOUNTNAME\":\"" + bankObj.get("ACCOUNTNAME") + "\",\n" +
                                        "\"INBANK\":\"" + bankObj.get("INBANK") + "\",\n" +
                                        "\"ACCOUNTSTATE\":\"" + bankObj.get("ACCOUNTSTATE") + "\",\n" +
                                        "\"PRIVATEORPUBLIC\":\"" + bankObj.get("PRIVATEORPUBLIC") + "\",\n" +
                                        "\"CURRENCYLIST\":\"" + bankObj.get("CURRENCYLIST") + "\",\n" +
                                        "\"ISMAIN\":\"" + bankObj.get("ISMAIN") + "\",\n" +
                                        "\"COUNTRY\":\"" + bankObj.get("COUNTRY") + "\",\n" +
                                        "\"PROVINCE\":\"" + bankObj.get("PROVINCE") + "\",\n" +
                                        "\"CITY\":\"" + bankObj.get("CITY") + "\",\n" +
                                        "\"REMARK\":\"" + bankObj.get("REMARK") + "\"\n" +
                                        "     },";
                            }
                            //去掉拼接的最后一个字符
                            GsJson = GsJson.substring(0, GsJson.lastIndexOf(','));
                        }
                        GsJson += "]\n" + "}";
                        GsJson = GsJson.replace("null", "");
                        //调用GS接口，推送给GS浪潮，获取返回值;
                        //1、推送用户档案
                        String gsUrl = "https://" + IP + ":" + PORT + "/api/jg/syncbddata/v1.0/bdsyncinterface/syncWldw";
                        String returnMSG = HttpRequest.post(gsUrl)
                                .header("Content-Type", "application/json")
                                .header("Accept-Language", "zh-CHS")
                                .header("X-ECC-Current-Tenant", ECC)
                                .header("Authorization", Bearer).timeout(200000)
                                .body(GsJson).execute().body();
                        if (!returnMSG.isEmpty()) {
                            String logInsert = "";
                            JSONObject returnObj = JSONObject.parseObject(returnMSG);
                            //成功
                            if (returnObj.get("code").equals("0")) {
                                //写入日志表
                                int loginsert = loginfo.loginfo(jdbcTemplate, methodName, LocalDateTime.now().toString(), "成功", GsJson, returnMSG, "", "", gsUrl, (String) gSmap.get("TS"));
                                if (loginsert > 0) {
                                    //System.out.println("日志写入成功！！");
                                } else {
                                    System.out.println("日志写入失败！！");
                                }
                                //失败
                            } else if (returnObj.get("code").equals("1")) {
                                //写入日志表
                                int loginsert = loginfo.loginfo(jdbcTemplate, methodName, LocalDateTime.now().toString(), "失败", GsJson, returnMSG, "", "", gsUrl, (String) gSmap.get("TS"));
                                if (loginsert > 0) {
                                    //System.out.println("日志写入成功！！");
                                } else {
                                    System.out.println("日志写入失败！！");
                                }
                            } else if (returnObj.get("code") == null && ("").equals(returnObj.get("code"))) {
                                //写入日志表
                                int loginsert = loginfo.loginfo(jdbcTemplate, methodName, LocalDateTime.now().toString(), "数据返回异常", GsJson, returnMSG, "", (String) gSmap.get("ID"), gsUrl, (String) gSmap.get("TS"));
                                if (loginsert > 0) {
                                    //System.out.println("日志写入成功！！");
                                } else {
                                    System.out.println("日志写入失败！！");
                                }
                            }
                        }
                    }
                }
            } else {
                System.out.println("暂无新数据推送");
            }

        } catch (Exception e) {
            throw new RuntimeException(e);
        }finally {
            //关闭链接
            DataSourceUtil.closeOracleSession();
            DataSourceUtil.closeMysqlSession();
        }
    }



}
